﻿using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Linq;

using SY.Uap;
using SY.Uap.Entity;
using SY.WebSite.Entity;
using SY.WebSite.Utility;
using SY.WebSite.BLL;
using System;

namespace SY.WebSite.Web.Handler
{
    public class ApiHandler : ApiWebHandler, IHttpHandler
    {
        public new void ProcessRequest(HttpContext context)
        {
            base.ProcessRequest(context);

            switch (Action)
            {
                case "login":
                    Login();
                    break;
                case "checkForUpdate":
                    CheckForUpdate();
                    break;
                case "topAvailable":
                    TopAvailable();
                    break;
                case "transfer":
                    Transfer();
                    break;
                case "submitSuggest":
                    SubmitSuggest();
                    break;
                case "mySuggests":
                    MySuggestList();
                    break;
                case "suggestRank":
                    SuggestRank();
                    break;
                case "getUserList":
                    GetUserList();
                    break;

                case "postReward":
                    PostReward();
                    break;
                case "rewardList":
                    RewardList();
                    break;
                case "rewardRank":
                    RewardRank();
                    break;
                case "rewardResponse":
                    RewardResponseList();
                    break;
                case "postResponse":
                    PostResponse();
                    break;
                case "finishReward":
                    FinishReward();
                    break;
                case "reviewResponse":
                    ReviewResponse();
                    break;

                case "queryIntegrationTransaction":
                    QueryIntegrationTransaction();
                    break;
            }

            context.Response.End();
        }

        public void QueryIntegrationTransaction()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 20);

            string start = RequestStringParam("start");
            string end = RequestStringParam("end");

            int type = RequestIntParam("type");//类型：0全部 1收入 2支出

            User user = BizUser.GetByKey(CurrentUser.UserId);
            if (user == null)
                BreakResponse();

            IEnumerable<IntegrationTransaction> list = type == 0 ? BizIntegrationTransaction.GetListByUserId(CurrentUser.UserId) : BizIntegrationTransaction.GetListByUserIdAndType(CurrentUser.UserId, type);

            if(!string.IsNullOrEmpty(start))
            {
                DateTime starDate;
                if(DateTime.TryParse(start, out starDate))
                {
                    list = list.Where(l => l.DateTime >= starDate);
                }
                else
                {
                    BreakResponse();
                }
            }

            if (!string.IsNullOrEmpty(end))
            {
                DateTime endDate;
                if (DateTime.TryParse(end, out endDate))
                {
                    list = list.Where(l => l.DateTime <= endDate.AddDays(1));
                }
                else
                {
                    BreakResponse();
                }
            }

            ApiJsonTransfer jt = new ApiJsonTransfer();
            jt.SetPagination(list.Count(), pageSize);
            jt.Add("list", list.Skip(pageSize * pageIndex).Take(pageSize));
            jt.Add("jobName", user.JobName);
            jt.Add("integration", BizIntegration.GetByKey(CurrentUser.UserId));
            Response.Write(jt);
        }

        public void ReviewResponse()
        {
            int id = Tools.Web.Request.GetFormInt("id", 0);
            int rewardId = Tools.Web.Request.GetFormInt("rewardId", 0);
            int amount = Tools.Web.Request.GetFormInt("amount", 0);

            if (id <= 0 || rewardId <= 0)
                BreakResponse();

            Reward reward = BizReward.AllForMobile().FirstOrDefault(l => l.Id == rewardId);
            if (reward == null || reward.UserId != CurrentUser.UserId || reward.Status == 1)
                BreakResponse();

            IEnumerable<RewardResponse> list = BizRewardResponse.GetListByRewardId(rewardId);
            RewardResponse response = list.FirstOrDefault(l => l.Id == id);
            if (response == null || response.Status != 0)
                BreakResponse();

            var tempAmount = list.Sum(l => l.Amount);
            if (tempAmount + amount > reward.Amount)
                BreakResponse("奖赏素币不能超过悬赏总素币");

            response.Status = 1;
            response.Amount = amount;

            int result = BizRewardResponse.Update(response);
            if (result > 0)
            {
                ApiJsonTransfer jt = new ApiJsonTransfer();
                jt.SetApiSuccess();

                Response.Write(jt);
                Response.End();
            }

            response.Status = 0;
            response.Amount = 0;
            BreakResponse();
        }

        public void FinishReward()
        {
            int id = Tools.Web.Request.GetFormInt("id", 0);

            if (id <= 0)
                BreakResponse();

            Reward reward = BizReward.All().FirstOrDefault(l => l.Id == id);
            if (reward == null || reward.Status == 1 || reward.UserId != CurrentUser.UserId)
                BreakResponse();

            if (BizReward.Finish(reward))
            {
                ApiJsonTransfer jt = new ApiJsonTransfer();
                jt.SetApiSuccess();

                Response.Write(jt);
                Response.End();
            }

            BreakResponse();
        }

        public void PostResponse()
        {
            string content = Tools.Web.Request.GetFormString("description");
            int id = Tools.Web.Request.GetFormInt("id", 0);

            if (id <= 0 || string.IsNullOrEmpty(content))
                BreakResponse();

            Reward reward = BizReward.AllForMobile().FirstOrDefault(l => l.Id == id);
            if (reward == null)
                BreakResponse("悬赏不存在");
            else if (reward.Status == 1)
                BreakResponse("悬赏已结束");
            else if (reward.EndTime <= DateTime.Now)
            {
                reward.Status = 2;
                BreakResponse("悬赏已截止");
            }

            RewardResponse response = new RewardResponse
            {
                RewardId = id,
                Content = Tools.StringUtil.HtmlEncode(content),
                UserId = CurrentUser.UserId,
                UserName = CurrentUser.UserName
            };

            int result = BizRewardResponse.Add(response);
            if (result > 0)
            {
                ApiJsonTransfer jt = new ApiJsonTransfer();
                jt.SetApiSuccess();

                Response.Write(jt);
                Response.End();
            }

            BreakResponse();
        }

        public void PostReward()
        {
            string title = Tools.Web.Request.GetFormString("title");
            string content = Tools.Web.Request.GetFormString("description");
            string end = Tools.Web.Request.GetFormString("end");
            string userList = Tools.Web.Request.GetFormString("userList");

            int amount = Tools.Web.Request.GetFormInt("amount", 0);
            int type = Tools.Web.Request.GetFormInt("type", 0);

            DateTime endTime = DateTime.Now;
            if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(content) || string.IsNullOrEmpty(end) ||
                type > 1 || type < 0 || amount == 0 || !DateTime.TryParse(end, out endTime))
                BreakResponse();

            Integration integration = BizIntegration.GetByKey(CurrentUser.UserId);
            if ((type == 1 && amount > integration.Available) || (type == 2 && amount > integration.Honor))
                BreakResponse("悬赏素币不足");

            Reward reward = new Reward
            {
                UserId = CurrentUser.UserId,
                UserName = CurrentUser.UserName,
                Title = Tools.StringUtil.HtmlEncode(title),
                Description = Tools.StringUtil.HtmlEncode(content),
                Amount = amount,
                MayParticipateList = string.IsNullOrEmpty(userList) ? "" : ("," + userList.Trim(',') + ","),
                EndTime = endTime,
                Type = type,
                Summary = Tools.StringUtil.GetSubString(Tools.StringUtil.RemoveHtml(content), 200, "...", Tools.StringUtil.StringFillOption.FillOneTimeWhenBeCut)
            };
            int result = BizReward.Add(reward);
            if (result > 0)
            {
                if (type == 1)
                {
                    integration.Available -= amount;
                }
                else
                {
                    integration.Honor -= amount;
                }
                integration.Freeze += amount;
                BizIntegration.Update(integration);

                ApiJsonTransfer jt = new ApiJsonTransfer();
                jt.SetApiSuccess();
                Response.Write(jt);
                Response.End();
            }

            BreakResponse();
        }

        public void RewardList()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 15);
            int userId = RequestIntParam("userId");

            string start = RequestStringParam("start");
            string end = RequestStringParam("end");
            string keyword = RequestStringParam("keyword");

            ApiJsonTransfer jt = new ApiJsonTransfer();
            IEnumerable<Reward> list = BizReward.AllForMobile();
            if (userId > 0)
                list = list.Where(l => l.UserId == userId);

            if (!string.IsNullOrEmpty(keyword))
                list = list.Where(l => l.Title.Contains(keyword) || l.Description.Contains(keyword));
            
            if (!string.IsNullOrEmpty(start))
            {
                DateTime starDate;
                if (DateTime.TryParse(start, out starDate))
                {
                    list = list.Where(l => l.CreateTime >= starDate);
                }
                else
                {
                    BreakResponse();
                }
            }

            if (!string.IsNullOrEmpty(end))
            {
                DateTime endDate;
                if (DateTime.TryParse(end, out endDate))
                {
                    list = list.Where(l => l.CreateTime <= endDate);
                }
                else
                {
                    BreakResponse();
                }
            }
            foreach (Reward tem in list.Where(l => l.Status == 0 && l.EndTime <= DateTime.Now))
            {
                tem.Status = 2;
            }
            var tempList = list.OrderByDescending(l=>l.EndTime).Skip(pageIndex * pageSize).Take(pageSize);

            jt.SetApiSuccess();
            jt.SetPagination(list.Count(), pageSize);
            jt.Add("list", tempList);

            Response.Write(jt);
        }

        public void RewardRank()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 15);
            int userId = RequestIntParam("userId");

            ApiJsonTransfer jt = new ApiJsonTransfer();
            IEnumerable<Hashtable> list = BizReward.RankList();

            if (userId > 0)
                list = list.Where(l => l["UserId"].ToString() == userId.ToString());

            jt.SetApiSuccess();
            jt.SetPagination(list.Count(), pageSize);
            jt.Add("list", list.Skip(pageIndex * pageSize).Take(pageSize));

            Response.Write(jt);
        }

        public void RewardResponseList() {
            int id = RequestIntParam("id");

            if (id <= 0)
                BreakResponse();

            Reward reward = BizReward.AllForMobile().FirstOrDefault(l => l.Id == id);
            if (reward == null)
                BreakResponse();

            IEnumerable<RewardResponse> list = BizRewardResponse.GetListByRewardId(id);

            string order = RequestStringParam("order");
            if (order == "asc")
                list = list.Reverse();

            foreach (RewardResponse response in list) {
                response.Content = Tools.StringUtil.HtmlDecode(response.Content);
            }

            ApiJsonTransfer jt = new ApiJsonTransfer();
            jt.SetApiSuccess();
            jt.Add("sum_count", list.Count());
            jt.Add("list", list);
            Response.Write(jt);
        }

        public void Login()
        {
            string userName = RequestStringParam("userName");
            string password = RequestStringParam("password");

            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                BreakResponse();

            ApiJsonTransfer jt = new ApiJsonTransfer();
            AppVersion version;
            switch (OS)
            {
                case "android":
                    version = JsonTransfer.DeserializeObject<AppVersion>(BizKeyValue.GetItemByTypeAndKey((int) KeyValueType.System, "android_version").Value);
                    if (version.Version == Version)
                        version.UpdateType = -1;
                    jt.Add("update", version);
                    break;
                case "ios":
                    version = JsonTransfer.DeserializeObject<AppVersion>(BizKeyValue.GetItemByTypeAndKey((int)KeyValueType.System, "ios_version").Value);
                    if (version.Version == Version)
                        version.UpdateType = -1;
                    jt.Add("update", version);
                    break;
            }

            ActionResult<ResultKey, User> result = BizUser.Login(userName, password);
            if (result.OK)
            {
                Integration integration = BizIntegration.GetByKey(result.ExtraData.UserId);

                jt.SetApiSuccess();
                jt.Add("deptName", result.ExtraData.DeptName);
                jt.Add("userInfo", integration);
                jt.Add("allUserHashcode", ToJson(BizUser.LoadUserList()).GetHashCode());

                Response.Write(jt);
                return;
            }

            switch (result.Result)
            {
                case ResultKey.UserNotFound:
                case ResultKey.WrongPassword:
                    BreakResponse("工号或密码错误");
                    break;
                case ResultKey.ForbiddenReferer:
                    BreakResponse("该账号限制登录");
                    break;
            }
        }

        public void GetUserList()
        {
            ApiJsonTransfer jt = new ApiJsonTransfer();
            jt.SetApiSuccess();
            IList<Hashtable> list = BizUser.LoadUserList();
            //foreach (Hashtable ht in list) {
            //    ht.Remove("name");
            //}
            jt.Add("list", list);
            jt.Add("allUserHashcode", ToJson(list).GetHashCode());
            Response.Write(jt);
        }

        public void TopAvailable()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 15);

            string user = RequestStringParam("user");

            IList<Hashtable> list = BizIntegration.GetIntegrationByUser(Tools.StringUtil.Nosql(user));// BizIntegration.GetTopAvailable();
            ApiJsonTransfer jt = new ApiJsonTransfer();
            jt.SetApiSuccess();

            jt.SetPagination(list.Count, pageSize);
            jt.Add("list", list.Skip(pageIndex * pageSize).Take(pageSize));
            Response.Write(jt);
        }

        #region 建议
        public void MySuggestList()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 15);

            ApiJsonTransfer jt = new ApiJsonTransfer();
            IEnumerable<Suggest> list = BizSuggest.MyList(CurrentUser.UserId);

            jt.SetApiSuccess();
            jt.SetPagination(list.Count(), pageSize);
            jt.Add("list",  list.Skip(pageIndex * pageSize).Take(pageSize));

            Response.Write(jt);
        }

        public void SuggestRank()
        {
            int pageIndex = RequestIntParam("pageIndex");
            int pageSize = RequestIntParam("pageSize", 15);
            int userId = RequestIntParam("userId");

            ApiJsonTransfer jt = new ApiJsonTransfer();
            IEnumerable<Hashtable> list = BizSuggest.RankList();

            if (userId > 0)
                list = list.Where(l => l["UserId"].ToString() == userId.ToString());

            jt.SetApiSuccess();
            jt.SetPagination(list.Count(), pageSize);
            jt.Add("list", list.Skip(pageIndex * pageSize).Take(pageSize));

            Response.Write(jt);
        }

        public void SubmitSuggest()
        {
            string title = Tools.Web.Request.GetFormString("title");
            string content = Tools.Web.Request.GetFormString("content");
            string dept = Tools.Web.Request.GetFormString("dept");

            if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(content))
                BreakResponse("标题或内容不能为空");

            Suggest suggest = new Suggest
            {
                UserId = CurrentUser.UserId,
                UserName = CurrentUser.UserName,
                DeptName = CurrentUser.DeptName,
                Title = Tools.StringUtil.HtmlEncode(title),
                Description = Tools.StringUtil.HtmlEncode(content),
                RelateDeptName = Tools.StringUtil.HtmlEncode(dept)
            };
            int result = BizSuggest.Add(suggest);
            if (result > 0)
                Response.Write(new JsonTransfer().SetApiSuccess());
            else
                BreakResponse();
        }
        #endregion

        public void Transfer()
        {
            string to = RequestStringParam("toUser");
            if (string.IsNullOrEmpty(to))
                BreakResponse("接收方不能为空");

            int amount = RequestIntParam("amount");
            string reason = RequestStringParam("reason");

            if(amount<=0)
                BreakResponse("交易的素币数必须大于0");

            if (string.IsNullOrEmpty(reason))
                BreakResponse("理由不能为空");

            User toUser = BizUser.GetByKey(int.Parse(to));
            if (toUser == null || toUser.Status == 1)
                BreakResponse("接收方不存在或者已被禁用");

            if (toUser.UserId == CurrentUser.UserId)
                BreakResponse("不能交易素币给自己");

            if (BizAuctionItemBid.CheckUserHaveBidding(CurrentUser.UserId))
            {
                BreakResponse("当前存在尚未结算的拍卖纪录，暂时不能交易素币");
            }

            bool result = BizIntegrationTransaction.Transaction(CurrentUser, toUser, amount, 3, Tools.StringUtil.HtmlEncode(reason));
            if (!result)
                BreakResponse("交易的素币超过您的可交易素币，请确认后重新操作");

            ApiJsonTransfer jt = new ApiJsonTransfer();
            jt.SetApiSuccess();
            Integration integration = BizIntegration.GetByKey(CurrentUser.UserId);
            jt.Add("userInfo", integration);

            Response.Write(jt);
        }


        public void CheckForUpdate()
        {
            ApiJsonTransfer jt = new ApiJsonTransfer();
            AppVersion version;
            switch (OS)
            {
                case "android":
                    version = JsonTransfer.DeserializeObject<AppVersion>(BizKeyValue.GetItemByTypeAndKey((int)KeyValueType.System, "android_version").Value);
                    if (version.Version == Version)
                        version.UpdateType = -1;
                    jt.Add("update", version);
                    break;
                case "ios":
                    version = JsonTransfer.DeserializeObject<AppVersion>(BizKeyValue.GetItemByTypeAndKey((int)KeyValueType.System, "ios_version").Value);
                    if (version.Version == Version)
                        version.UpdateType = -1;
                    jt.Add("update", version);
                    break;
                default:
                    BreakResponse("参数错误");
                    break;
            }
            Response.Write(jt);
        }

    }
}